package cn.ronghuanet.user.service.impl;

import cn.ronghuanet.basic.constants.WxConstants;
import cn.ronghuanet.basic.util.AjaxResult;
import cn.ronghuanet.basic.util.HttpUtil;
import cn.ronghuanet.user.domain.Logininfo;
import cn.ronghuanet.user.domain.User;
import cn.ronghuanet.user.domain.Wxuser;
import cn.ronghuanet.user.mapper.LogininfoMapper;
import cn.ronghuanet.user.mapper.UserMapper;
import cn.ronghuanet.user.mapper.WxuserMapper;
import cn.ronghuanet.user.service.ILogininfoService;
import cn.ronghuanet.basic.service.impl.BaseServiceImpl;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import sun.java2d.pipe.AAShapePipe;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 业务实现类：
 */
@Service
public class LogininfoServiceImpl extends BaseServiceImpl<Logininfo> implements ILogininfoService {
    @Autowired
    private LogininfoMapper logininfoMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private WxuserMapper wxuserMapper;
    @Autowired
    private UserMapper userMapper;

    @Override
    public AjaxResult login(Map<String, String> map) {
        String checkPass = map.get("checkPass");
        String account = map.get("account");
        String type = map.get("type");
        // 空值校验
        if (Objects.isNull(checkPass) || Objects.isNull(account)) {
            return AjaxResult.me().setSuccess(false).setMessage("参数不正确");
        }
        // 方案二： 使用账户 查到了 以后在匹配用户输入的密码
        Logininfo logininfo = logininfoMapper.findLoginInfoByAccountAndType(map);
        if (Objects.isNull(logininfo)) {
            return AjaxResult.me().setSuccess(false).setMessage("账号或密码错误");
        }
        // 密码加密以后在比较
        String password = DigestUtils.md5DigestAsHex((logininfo.getSalt() + checkPass).getBytes());
        if (!logininfo.getPassword().equals(password)) {
            return AjaxResult.me().setSuccess(false).setMessage("账号或密码错误");
        }
        HashMap<String, Object> map1 = getLoginMap(logininfo);
        return AjaxResult.me().setResultObj(map1);
    }


    private HashMap<String, Object> getLoginMap(Logininfo logininfo) {
        // 成功登录 生成token
        String token = UUID.randomUUID().toString();
        // 将token和Logininfo 存入redis
        redisTemplate.opsForValue().set(token, logininfo, 30, TimeUnit.MINUTES);
        // 数据脱敏
        logininfo.setSalt(null);
        logininfo.setPassword(null);
        // 返回数据
        HashMap<String, Object> map1 = new HashMap<>();
        map1.put("token", token);
        map1.put("logininfo", logininfo);
        return map1;
    }

    @Override
    public AjaxResult loginWechat(String code) {
        // 验证 code 空值
        if (StringUtils.isBlank(code)) {
            return AjaxResult.me().setSuccess(false).setMessage("微信授权参数异常");
        }
        // 准备好三个参数 code appid 密钥
        String url = WxConstants.GET_ACK_URL;
        url = url.replace("APPID", WxConstants.APPID);
        url = url.replace("SECRET", WxConstants.SECRET);
        url = url.replace("CODE", code);
        // 通过 参数 拿token   发起请求
        // 根据openid 查询是否有 wxuser数据
        String s = HttpUtil.httpGet(url);
        // 将字符串转换为JSON对象
        JSONObject jsonObject = JSONObject.parseObject(s);
        // 获取里面的 access—token 和 openid
        String access_token = jsonObject.getString("access_token");
        String openid = jsonObject.getString("openid");
        // 通过openid查询 wxuser表
        Wxuser wxuser = wxuserMapper.findByOpenId(openid);
        // 如果有就直接登录
        if (Objects.nonNull(wxuser)) {
            // 无感登录
            // 通过wxuser查查user
            User user = wxuserMapper.findByWxUserId(wxuser.getUserId());
            // 通过user查logininfo
            Logininfo logininfo = logininfoMapper.queryByPhone(user.getPhone());
            return AjaxResult.me().setResultObj(getLoginMap(logininfo));
        }
        // 如果没有就跳转一个页面让用户绑定手机
        HashMap<String, String> map = new HashMap<>();
        map.put("token", access_token);
        map.put("openid", openid);
        return AjaxResult.me().setSuccess(false).setResultObj(map);
    }

    @Override
    public AjaxResult binder(Map<String, String> map) {
        // 获取参数并且验证空值
        String phone = map.get("phone");
        String verifyCode = map.get("verifyCode");
        String accessToken = map.get("accessToken");
        String openid = map.get("openid");
        // 校验手机验证码
        if (StringUtils.isBlank(phone)
                || StringUtils.isBlank(verifyCode)
        ) {
            return AjaxResult.me().setSuccess(false).setMessage("参数异常。。。");
        }
        // 请求微信数据 token+openid 获取用户信息
        String url = WxConstants.GET_USER_URL;
        url = url.replace("ACCESS_TOKEN", accessToken);
        url = url.replace("OPENID", openid);
        String s = HttpUtil.httpGet(url);
        // 将返回的数据类型转为 json对象
        JSONObject jsonObject = JSONObject.parseObject(s);

        Integer sex = jsonObject.getInteger("sex");
        String province = jsonObject.getString("province");
        String city = jsonObject.getString("city");
        String country = jsonObject.getString("country");
        String headimgurl = jsonObject.getString("headimgurl");
        String nickname = jsonObject.getString("nickname");
        String unionid = jsonObject.getString("unionid");

        // 封装wxuser
        Wxuser wxuser = new Wxuser();
        wxuser.setAddress(country+":"+province+":"+city);
        wxuser.setHeadimgurl(headimgurl);
        wxuser.setSex(sex);
        wxuser.setNickname(nickname);
        wxuser.setUnionid(unionid);
        wxuser.setOpenid(openid);
        // 封装 user对象
        User user = wxuser2User(wxuser,phone);
        // 封装 logininfo对象
        Logininfo logininfo = user2LoginInfo(user);
        logininfoMapper.insert(logininfo);
        user.setLogininfoId(logininfo.getId());
        userMapper.insert(user);
        wxuser.setUserId(user.getId());
        wxuserMapper.insert(wxuser);
        // 无感登录
        HashMap<String, Object> loginMap = getLoginMap(logininfo);
        return AjaxResult.me().setResultObj(loginMap);
    }
    private User wxuser2User(Wxuser wxuser,String phone){
        User user = new User();
        user.setPhone(phone);
        user.setCreatetime(new Date());
        user.setState(1);
        user.setHeadImg(wxuser.getHeadimgurl());
        return user;
    }
    private Logininfo user2LoginInfo(User user){
        Logininfo logininfo = new Logininfo();
        BeanUtils.copyProperties(user,logininfo);
        logininfo.setDisable(false);
        logininfo.setType(1);

        return logininfo;
    }
}
